BLOCK_ROOT_DEV = "hda"
-def XmTestDomain(name=None, extraOpts=None, config="/dev/null"):
- if ENABLE_VMX_SUPPORT:
- return XmTestVmxDomain(name, extraOpts, config)
+def getDeviceModel():
+ """Get the path to the device model based on
+ the architecture reported in uname"""
+ arch = os.uname()[4]
+ if re.search("64", arch):
+ return "/usr/lib64/xen/bin/qemu-dm"
else:
- return XmTestPvDomain(name, extraOpts, config)
+ return "/usr/lib/xen/bin/qemu-dm"
def getDefaultKernel():
+ """Get the path to the default DomU kernel"""
dom0Ver = commands.getoutput("uname -r");
domUVer = dom0Ver.replace("xen0", "xenU");
return "/boot/vmlinuz-" + domUVer;
+def getUniqueName():
+ """Get a uniqueish name for use in a domain"""
+ unixtime = int(time.time())
+ test_name = sys.argv[0]
+ test_name = re.sub("\.test", "", test_name)
+ test_name = re.sub("[\/\.]", "", test_name)
+ name = "%s-%i" % (test_name, unixtime)
+
+ return name
+
+def getRdPath():
+ rdpath = os.environ.get("RD_PATH")
+ if not rdpath:
+ rdpath = "../../ramdisk"
+ rdpath = os.path.abspath(rdpath)
+
+ return rdpath
+
+ParavirtDefaults = {"memory" : 64,
+ "vcpus" : 1,
+ "kernel" : getDefaultKernel(),
+ "root" : "/dev/ram0",
+ "ramdisk" : getRdPath() + "/initrd.img"
+ }
+VmxDefaults = {"memory" : 64,
+ "vcpus" : 1,
+ "nics" : 0,
+ "disk" : ["file:%s/disk.img,ioemu:%s,w" %
+ (getRdPath(), BLOCK_ROOT_DEV)],
+ "kernel" : "/usr/lib/xen/boot/vmxloader",
+ "builder" : "vmx",
+ "sdl" : 0,
+ "vnc" : 0,
+ "vncviewer" : 0,
+ "nographic" : 1,
+ "serial" : "pty",
+ "device_model" : getDeviceModel()
+ }
+
+if ENABLE_VMX_SUPPORT:
+ configDefaults = VmxDefaults
+else:
+ configDefaults = ParavirtDefaults
+
+class XenConfig:
+ """An object to help create a xen-compliant config file"""
+ def __init__(self):
+ self.defaultOpts = {}
+
+ # These options need to be lists
+ self.defaultOpts["disk"] = []
+ self.defaultOpts["vif"] = []
+
+ self.opts = self.defaultOpts
+
+ def toString(self):
+ """Convert this config to a string for writing out
+ to a file"""
+ string = "# Xen configuration generated by xm-test\n"
+ for k, v in self.opts.items():
+ if isinstance(v, int):
+ piece = "%s = %i" % (k, v)
+ elif isinstance(v, list) and v:
+ piece = "%s = %s" % (k, v)
+ elif isinstance(v, str) and v:
+ piece = "%s = \"%s\"" % (k, v)
+ else:
+ piece = None
+
+ if piece:
+ string += "%s\n" % piece
+
+ return string
+
+ def write(self, filename):
+ """Write this config out to filename"""
+ output = file(filename, "w")
+ output.write(self.toString())
+ output.close()
+
+ def __str__(self):
+ """When used as a string, we represent ourself by a config
+ filename, which points to a temporary config that we write
+ out ahead of time"""
+ filename = "/tmp/xm-test.conf"
+ self.write(filename)
+ return filename
+
+ def setOpt(self, name, value):
+ """Set an option in the config"""
+ if name in self.opts.keys() and isinstance(self.opts[name], list) and not isinstance(value, list):
+ self.opts[name] = [value]
+ else:
+ self.opts[name] = value
+
+ def appOpt(self, name, value):
+ """Append a value to a list option"""
+ if name in self.opts.keys() and isinstance(self.opts[name], list):
+ self.opts[name].append(value)
+
+ def getOpt(self, name):
+ """Return the value of a config option"""
+ if name in self.opts.keys():
+ return self.opts[name]
+ else:
+ return None
+
+ def setOpts(self, opts):
+ """Batch-set options from a dictionary"""
+ for k, v in opts.items():
+ self.setOpt(k, v)
+
+ def clearOpts(self, name=None):
+ """Clear one or all config options"""
+ if name:
+ self.opts[name] = self.defaultOpts[name]
+ else:
+ self.opts = self.defaultOpts
class DomainError(Exception):
def __init__(self, msg, extra="", errorcode=0):
def __str__(self):
return str(self.msg)
-class XenDomain:
-
- def __init__(self, opts={}, config="/dev/null"):
- """Create a domain object. Optionally take a
- dictionary of 'xm' options to use"""
-
- self.domID = None;
- self.config = config
-
- if not opts.has_key("name"):
- raise DomainError("Missing `name' option")
- if not opts.has_key("memory"):
- raise DomainError("Missing `memory' option")
- if not opts.has_key("kernel"):
- raise DomainError("Missing `kernel' option")
- self.opts = opts
-
- self.configVals = None
-
- def __buildCmdLine(self):
- c = "xm create %s" % self.config
+class XenDomain:
- for k in self.opts.keys():
- c += " %s=%s" % (k, self.opts[k])
-
- return c
+ def __init__(self, name=None, config=None):
+ """Create a domain object.
+ @param config: String filename of config file
+ """
- def getUniqueName(self):
- #
- # We avoid multiple duplicate names
- # here because they stick around in xend
- # too long
- #
- unixtime = int(time.time())
- test_name = sys.argv[0]
- test_name = re.sub("\.test", "", test_name)
- test_name = re.sub("[\/\.]", "", test_name)
- name = "%s-%i" % (test_name, unixtime)
+ if name:
+ self.name = name
+ else:
+ self.name = getUniqueName()
- return name
+ self.config = config
def start(self):
- if self.configVals:
- self.__writeConfig("/tmp/xm-test.conf")
- self.config = "/tmp/xm-test.conf"
-
- commandLine = self.__buildCmdLine()
-
- ret, output = traceCommand(commandLine);
-
- try:
- self.domID = self.getId()
- except:
- self.domID = -1;
+ ret, output = traceCommand("xm create %s" % self.config)
if ret != 0:
raise DomainError("Failed to create domain",
errorcode=ret)
def stop(self):
- prog = "xm";
- cmd = " shutdown ";
+ prog = "xm"
+ cmd = " shutdown "
- ret, output = traceCommand(prog + cmd + self.opts["name"]);
+ ret, output = traceCommand(prog + cmd + self.config.getOpt("name"))
- return ret;
+ return ret
def destroy(self):
- prog = "xm";
- cmd = " destroy ";
+ prog = "xm"
+ cmd = " destroy "
- ret, output = traceCommand(prog + cmd + self.opts["name"]);
+ ret, output = traceCommand(prog + cmd + self.config.getOpt("name"))
- return ret;
+ return ret
def getName(self):
- return self.opts["name"];
+ return self.name
def getId(self):
return domid(self.getName());
- def configSetVar(self, key, value):
- if not self.configVals:
- self.configVals = {}
-
- self.configVals[key] = value
-
- def configAddDisk(self, pdev, vdev, acc):
- if not self.configVals:
- self.configVals = {}
- if not self.configVals.has_key("disk"):
- self.configVals["disk"] = []
+class XmTestDomain(XenDomain):
- self.configVals["disk"].append("%s,%s,%s" % (pdev,vdev,acc))
+ def __init__(self, name=None, extraConfig=None, baseConfig=configDefaults):
+ """Create a new xm-test domain
+ @param name: The requested domain name
+ @param extraConfig: Additional configuration options
+ @param baseConfig: The initial configuration defaults to use
+ """
+ config = XenConfig()
+ config.setOpts(baseConfig)
+ if extraConfig:
+ config.setOpts(extraConfig)
- def configAddVif(self, type, mac, bridge):
- if not self.configVals:
- self.configVals = {}
-
- if not self.configVals.has_key("vif"):
- self.configVals["vif"] = []
-
- if mac:
- self.configVals["vif"].append("%s,%s,%s" % (type,mac,bridge))
- else:
- self.configVals["vif"].append("%s,%s" % (type,bridge))
+ if name:
+ config.setOpt("name", name)
+ elif not config.getOpt("name"):
+ config.setOpt("name", getUniqueName())
- def __writeConfig(self, configFileName):
-
- conf = file(configFileName, "w")
-
- for k,v in self.configVals.items():
- print >>conf, "%s = %s" % (k, v)
-
- conf.close()
-
-class XmTestVmxDomain(XenDomain):
-
- def __prepareBlockRoot(self, rdpath):
- image = os.path.abspath(rdpath + "/disk.img")
- self.configAddDisk("file:%s" % image, "ioemu:%s" % BLOCK_ROOT_DEV, "w")
-
- def __prepareVif(self):
- self.configAddVif("type=ioemu", None, "bridge=xenbr0")
-
- def __prepareDeviceModel(self):
- arch = os.uname()[4]
- if re.search('64', arch):
- self.configSetVar("device_model", "\"/usr/lib64/xen/bin/qemu-dm\"")
- else:
- self.configSetVar("device_model", "\"/usr/lib/xen/bin/qemu-dm\"")
-
- def __init__(self, name=None, extraOpts=None, config="/dev/null"):
-
- rdpath = os.environ.get("RD_PATH")
- if not rdpath:
- rdpath = "../../ramdisk"
-
- self.opts = {}
- self.configVals = {}
-
- # Defaults
- self.defaults = {"memory" : 64,
- "vcpus" : 1,
- "kernel" : "/usr/lib/xen/boot/vmxloader",
- "builder" : "\'vmx\'",
- "name" : name or self.getUniqueName()
- }
-
- self.domID = None;
- self.config = config;
-
- self.__prepareBlockRoot(rdpath)
- #self.__prepareVif()
- self.__prepareDeviceModel()
- #self.configSetVar("boot","\'c\'")
- self.configSetVar("sdl","0")
- self.configSetVar("vnc","0")
- self.configSetVar("vncviewer","0")
- self.configSetVar("nographic","1")
- self.configSetVar("serial","\'pty\'")
-
- # Copy over defaults
- for key in self.defaults.keys():
- self.opts[key] = self.defaults[key]
-
- # Merge in extra options
- if extraOpts:
- for key in extraOpts.keys():
- self.opts[key] = extraOpts[key]
+ XenDomain.__init__(self, config.getOpt("name"), config=config)
def start(self):
- """We know how about how long everyone will need to wait
- for our disk image to come up, so we do it here as a convenience"""
-
-# for i in range(0,5):
-# status, output = traceCommand("xm list")
-
XenDomain.start(self)
- waitForBoot()
+ if ENABLE_VMX_SUPPORT:
+ waitForBoot()
def startNow(self):
XenDomain.start(self)
- def getMem(self):
- return int(self.opts["memory"])
-
def minSafeMem(self):
return 16
-class XmTestPvDomain(XenDomain):
-
- def __init__(self, name=None, extraOpts=None, config="/dev/null"):
-
- rdpath = os.environ.get("RD_PATH")
- if not rdpath:
- rdpath = "../../ramdisk"
-
- self.opts = {}
- self.configVals = None
-
- # Defaults
- self.defaults = {"memory" : 64,
- "vcpus" : 1,
- "kernel" : getDefaultKernel(),
- "root" : "/dev/ram0",
- "name" : name or self.getUniqueName(),
- "ramdisk" : rdpath + "/initrd.img"
- }
-
- self.domID = None;
- self.config = config;
-
- # Copy over defaults
- for key in self.defaults.keys():
- self.opts[key] = self.defaults[key]
-
- # Merge in extra options
- if extraOpts:
- for key in extraOpts.keys():
- self.opts[key] = extraOpts[key]
-
- def start(self):
- """We know how about how long everyone will need to wait
- for our ramdisk to come up, so we do it here as a convenience"""
+if __name__ == "__main__":
-# for i in range(0,5):
-# status, output = traceCommand("xm list")
+ c = XenConfig()
- XenDomain.start(self)
-# waitForBoot()
+ c.setOpt("foo", "bar")
+ c.setOpt("foob", 1)
+ opts = {"opt1" : 19,
+ "opt2" : "blah"}
+ c.setOpts(opts)
- def startNow(self):
- XenDomain.start(self)
+ c.setOpt("disk", "phy:/dev/ram0,hda1,w")
+ c.appOpt("disk", "phy:/dev/ram1,hdb1,w")
- def getMem(self):
- return int(self.opts["memory"])
+ print str(c)
- def minSafeMem(self):
- return 16
+
-if __name__ == "__main__":
+# c.write("/tmp/foo.conf")
- d = XmTestDomain();
+# d = XmTestDomain();
+#
+# d.start();
- d.start();